home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0696.zip
/
DWYER.ZIP
/
COLISION.TST
/
CLSNDATA.C
next >
Wrap
C/C++ Source or Header
|
1996-03-26
|
4KB
|
142 lines
/* ============ */
/* ClsnData.c */
/* ============ */
#include <clsndefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define FULL_SIZE ((unsigned)RAND_MAX+1U)
ULONG ChkBits[FULL_SIZE];
static
UCHAR bit_mask[] = { 1 << 7, 1 << 6, 1 << 5, 1 << 4,
1 << 3, 1 << 2, 1 << 1, 1
};
/* INDENT ON */
/* ==================================================== */
/* LinTrp - Interpolates X0 Linearly in [X1,Y1],[X2,Y2] */
/* ==================================================== */
static double
LinTrp(double X0, double X1, double Y1, double X2, double Y2)
{
return (X1 == X2) ? Y1 : Y1 + (Y2 - Y1) / (X2 - X1) * (X0 - X1);
}
/* ==================================================================== */
/* SetBit - sets bit at bit_posn in bit_ary to bit_val */
/* ==================================================================== */
static void
SetBit(UCHAR *bit_ary, ULONG bit_posn, UCHAR bit_val)
{
if (bit_val) /* set the bit */
{
bit_ary[bit_posn >> 3] |= bit_mask[bit_posn & 0x07];
}
else /* clear the bit */
{
bit_ary[bit_posn >> 3] &= ~bit_mask[bit_posn & 0x07];
}
}
/* ==================================================================== */
/* TestBit = returns 1 if bit at bit_posn in bit_ary is a 1, else 0 */
/* ==================================================================== */
static UCHAR
TestBit(UCHAR *bit_ary, ULONG bit_posn)
{
return((UCHAR)(bit_ary[bit_posn >> 3] & bit_mask[bit_posn & 0x07]));
}
/* ==================================================================== */
/* GetBitVector - Returns a bit vector of observations from RandFun() */
/* ==================================================================== */
static ULONG
GetBitVector(CLSN_DATA_STRU *ClsnData)
{
int k;
ULONG BitVector = 0;
ULONG Next;
for (k = 1; k <= ClsnData->NumParts; ++k)
{
Next = (ULONG)(ClsnData->RandFun() & ClsnData->BitMask);
BitVector = (BitVector << ClsnData->NumBits) | Next;
}
ClsnData->NumVariates += ClsnData->NumParts;
return (BitVector);
}
/* ==================================================================== */
/* TerpHitProb - Interpolates in Probability Table for NumHits */
/* ==================================================================== */
static void
TerpHitProb(CLSN_DATA_STRU *ClsnData)
{
int k;
double X0, Y0, X1, Y1, X2, Y2;
for (k = TMAX - 2; k >= 0; --k)
{
if (ClsnData->NumHits < ClsnData->ClsnStats[k])
{
break;
}
}
if (k < 0)
{
ClsnData->HitProb = 1.0;
}
else if (ClsnData->NumHits == 0)
{
ClsnData->HitProb = 0.0;
}
else
{
X1 = (double)ClsnData->ClsnStats[k];
Y1 = ClsnData->ClsnProbs[k];
X2 = (double)ClsnData->ClsnStats[k+1];
Y2 = ClsnData->ClsnProbs[k+1];
X0 = (double)ClsnData->NumHits;
Y0 = LinTrp(X0, X1, Y1, X2, Y2);
ClsnData->HitProb = Y0;
}
}
/* ==================================================================== */
/* GetCollisionData - Records Number of Collisions in M urns of N balls */
/* ==================================================================== */
void
GetCollisionData(CLSN_DATA_STRU *ClsnData)
{
UINT k;
ULONG BitVctr;
UINT ClsnCt = 0;
for (k = 0; k < FULL_SIZE; ++k)
{
ChkBits[k] = 0;
}
for (k = 0; k < ClsnData->NumObs; ++k)
{
BitVctr = GetBitVector(ClsnData);
assert(BitVctr < (ULONG)ClsnData->NumCategories);
if (TestBit((UCHAR *)ChkBits, BitVctr) == 0)
{
SetBit((UCHAR *)ChkBits, BitVctr, 1);
}
else
{
++ClsnCt;
}
}
/* ----------------------------------------------- */
/* Store Collision Count & Interpolate Probability */
/* ----------------------------------------------- */
ClsnData->NumHits = ClsnCt;
TerpHitProb(ClsnData);
}